#include "../config/config.h"
#include "../config/cabrillo_config.h"
#include "main_app.h"
#include "../ui/ui_manager.h"
#include "../ui/function_button_manager.h"
#include "../radio/radio_manager.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <signal.h>    // 添加信号处理头文件
#include <unistd.h>    // 添加unistd头文件
#include <cstring>

// Static member variable definitions
HelpWindow* MainApp::helpWindowInstance = nullptr;
LogGridDialog* MainApp::logWindowInstance = nullptr;
MapWindow* MainApp::mapWindowInstance = nullptr;
GtkWidget* MainApp::helpWindowWidget = nullptr;
GtkWidget* MainApp::logWindowWidget = nullptr;
GtkWidget* MainApp::mapWindowWidget = nullptr;
gboolean MainApp::helpWindowCreated = FALSE;
gboolean MainApp::logWindowCreated = FALSE;
gboolean MainApp::mapWindowCreated = FALSE;
HttpServer* MainApp::httpServer = nullptr;
gboolean MainApp::isMainWindowClosing = FALSE;  // 初始化静态变量
CTYDatParser MainApp::parser;  // 定义静态成员变量

// Global variables
extern BaseConfig baseConfig;
extern std::map<std::string, std::map<std::string, std::string>> config;

// 信号处理函数声明
static void signal_handler(int signal);

// Function to load FunctionKeyConfig.ini
std::map<std::string, std::map<std::string, std::string>> MainApp::loadFunctionKeyConfig() {
    std::map<std::string, std::map<std::string, std::string>> config;
    
    // Load config file directly from the config directory relative to the executable
    char* exec_path = g_file_read_link("/proc/self/exe", NULL);
    char* config_file_path = nullptr;
    
    if (exec_path) {
        char* exec_dir = g_path_get_dirname(exec_path);
        config_file_path = g_build_filename(exec_dir, "config", "FunctionKeyConfig.ini", NULL);
        g_free(exec_dir);
        g_free(exec_path);
    }
    
    std::string config_path;
    bool config_found = false;
    
    if (config_file_path) {
        std::ifstream file(config_file_path);
        if (file.is_open()) {
            config_path = config_file_path;
            config_found = true;
            std::cout << "找到配置文件: " << config_path << std::endl;
            file.close();
        }
        g_free(config_file_path);
    }
    
    if (!config_found) {
        std::cerr << "无法找到FunctionKeyConfig.ini文件" << std::endl;
        return config;
    }
    
    std::ifstream file(config_path);
    if (!file.is_open()) {
        std::cerr << "无法打开FunctionKeyConfig.ini文件: " << config_path << std::endl;
        return config;
    }
    
    std::string line;
    std::string current_section;
    
    std::cout << "开始解析配置文件..." << std::endl;
    
    while (std::getline(file, line)) {
        //去掉字符串首尾回车
        line.erase(0, line.find_first_not_of(" \t\r\n"));
        line.erase(line.find_last_not_of(" \t\r\n") + 1);
        
        // Skip empty lines and comments
        if (line.empty() || line[0] == '#' || line[0] == ';') {
            continue;
        }
        
        // Check for section header
        if (line[0] == '[' && line[line.size() - 1] == ']') {
            current_section = line.substr(1, line.size() - 2);
            std::cout << "发现section: " << current_section << std::endl;
            continue;
        }
        
        // Parse key=value pairs
        size_t equal_pos = line.find('=');
        if (equal_pos != std::string::npos) {
            std::string key = line.substr(0, equal_pos);
            std::string value = line.substr(equal_pos + 1);
            
            // Trim whitespace
            key.erase(0, key.find_first_not_of(" \t"));
            key.erase(key.find_last_not_of(" \t") + 1);
            value.erase(0, value.find_first_not_of(" \t"));
            value.erase(value.find_last_not_of(" \t") + 1);
            
            if (!current_section.empty()) {
                config[current_section][key] = value;
                // std::cout << "  添加配置项: " << key << " = " << value << std::endl;
            }
        }
    }
    
    file.close();
    std::cout << "成功加载配置文件: " << config_path << std::endl;
    std::cout << "总共加载了 " << config.size() << " 个section" << std::endl;
    
    return config;
}

void MainApp::set_dtpl_red_font(GtkBuilder *builder,std::string dtplname) {
    GtkWidget *dtpl = GTK_WIDGET(gtk_builder_get_object(builder, dtplname.c_str()));
    if (dtpl) {
        GtkCssProvider *provider = gtk_css_provider_new();
        gtk_css_provider_load_from_data(provider, 
            ("#" + dtplname + " { color: red; font-weight: bold; }").c_str(), -1, NULL);
        GtkStyleContext *context = gtk_widget_get_style_context(dtpl);
        if (context) {
            gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(provider), 
                GTK_STYLE_PROVIDER_PRIORITY_USER);
        }
        g_object_unref(provider);
    }
}

void MainApp::on_dtpl_button_clicked(GtkWidget *widget, gpointer data) {
    GtkBuilder *builder = GTK_BUILDER(data);
    
    // 获取按钮ID
    const gchar *button_id = gtk_buildable_get_name(GTK_BUILDABLE(widget));
    if (!button_id) {
        std::cerr << "无法获取按钮ID" << std::endl;
        return;
    }
    
    std::string button_name(button_id);
    std::cout << "波段按钮 '" << button_name << "' 被点击" << std::endl;
    
    // 从按钮ID中提取波段值（移除"dtpl"前缀）
    if (button_name.length() > 4 && button_name.substr(0, 4) == "dtpl") {
        std::string band = button_name.substr(4);
        
        // 更新RadioConfig.CurrentBand
        baseConfig.currentBand = band;
        std::cout << "已更新当前波段为: " << band << std::endl;
        
        // 保存配置到文件
        if (!saveBaseConfig("config/config.ini")) {
            std::cerr << "无法保存配置到文件" << std::endl;
        } else {
            std::cout << "成功保存配置到文件" << std::endl;
        }
        
        // 更新UI中波段按钮的显示状态
        // 先将所有波段按钮恢复默认颜色（通过重新应用CSS）
        std::vector<std::string> bands = {"160", "80", "40", "30", "20", "15", "12", "10"};
        for (const std::string& b : bands) {
            GtkWidget *dtpl = GTK_WIDGET(gtk_builder_get_object(builder, ("dtpl" + b).c_str()));
            if (dtpl) {
                GtkCssProvider *provider = gtk_css_provider_new();
                std::string cssData = "#" + std::string("dtpl") + b + " { color: black; font-weight: normal; }";
                gtk_css_provider_load_from_data(provider, cssData.c_str(), -1, NULL);
                GtkStyleContext *context = gtk_widget_get_style_context(dtpl);
                if (context) {
                    gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(provider), 
                        GTK_STYLE_PROVIDER_PRIORITY_USER);
                }
                g_object_unref(provider);
            }
        }
        
        // 将当前波段按钮设置为红色
        set_dtpl_red_font(builder, button_name);
    } else {
        std::cerr << "无效的波段按钮ID: " << button_name << std::endl;
    }
}

void MainApp::load_config_to_buttons(GtkWidget *widget, const std::string& qsoType, gpointer user_data) {
    GtkBuilder *builder = GTK_BUILDER(user_data);
    
    // 定义按钮ID到配置键的映射
    std::map<std::string, std::string> buttonMap = {
        {"F1Button", "F1"},
        {"F2Button", "F2"},
        {"F3Button", "F3"},
        {"F4Button", "F4"},
        {"F5Button", "F5"},
        {"F6Button", "F6"},
        {"F7Button", "F7"},
        {"F8Button", "F8"},
        {"F9Button", "F9"},
        {"F10Button", "F10"},
        {"F11Button", "F11"},
        {"F12Button", "F12"},
        {"Fun1Button", "Fun1"},
        {"Fun2Button", "Fun2"},
        {"Fun3Button", "Fun3"},
        {"Fun4Button", "Fun4"},
        {"Fun5Button", "Fun5"},
        {"Fun6Button", "Fun6"},
        {"Fun7Button", "Fun7"}
    };
    
    // 获取默认的QSO类型（从Cabrillo配置中获取）
    CabrilloConfig* cabrilloConfig = CabrilloConfig::getInstance();
    std::string defaultQsoType = cabrilloConfig->get("CabrilloConfig.CONTEST", "DX");
    
    // 遍历按钮映射
    for (const auto& buttonPair : buttonMap) {
        const std::string& buttonId = buttonPair.first;
        const std::string& configKey = buttonPair.second;
        
        // 获取按钮控件
        GtkWidget* button = GTK_WIDGET(gtk_builder_get_object(builder, buttonId.c_str()));
        if (!button) {
            std::cerr << "找不到按钮: " << buttonId << std::endl;
            continue;
        }
        
        // 查找配置项
        std::string buttonLabel = configKey; // 默认使用配置键名
        if (config.find(qsoType) != config.end() && config[qsoType].find(configKey) != config[qsoType].end()) {
            // 使用配置文件中的值
            buttonLabel = config[qsoType][configKey];
        } else if (config.find(defaultQsoType) != config.end() && config[defaultQsoType].find(configKey) != config[defaultQsoType].end()) {
            // 如果当前QSO类型中没有找到，则使用默认QSO类型的配置
            buttonLabel = config[defaultQsoType][configKey];
        }
        
        // 设置按钮标签
        gtk_button_set_label(GTK_BUTTON(button), buttonLabel.c_str());
    }
}

// 新增函数：将配置加载到频率和WPM控件
void MainApp::load_config_to_frequency_wpm(GtkBuilder *builder) {
    // 获取频率输入框
    GtkWidget* frequency_entry = GTK_WIDGET(gtk_builder_get_object(builder, "edFrequency"));
    if (frequency_entry) {
        // 将当前频率设置到输入框，保留一位小数
        char frequency_str[20];
        snprintf(frequency_str, sizeof(frequency_str), "%.1f", baseConfig.currentFrequency);
        gtk_entry_set_text(GTK_ENTRY(frequency_entry), frequency_str);
    }
    
    // 获取WPM下拉框
    GtkWidget* wpm_combo = GTK_WIDGET(gtk_builder_get_object(builder, "cmbWpm"));
    if (wpm_combo) {
        // 将当前WPM设置为下拉框的活动项
        // WPM值对应下拉框的索引：5=0, 10=1, 15=2, 20=3, 25=4, 30=5, 35=6
        int wpm_index = -1;
        switch (baseConfig.wpm) {
            case 5: wpm_index = 0; break;
            case 10: wpm_index = 1; break;
            case 15: wpm_index = 2; break;
            case 20: wpm_index = 3; break;
            case 25: wpm_index = 4; break;
            case 30: wpm_index = 5; break;
            case 35: wpm_index = 6; break;
            default: 
                // 如果WPM值不在预设值中，使用最接近的值
                if (baseConfig.wpm < 5) wpm_index = 0;
                else if (baseConfig.wpm < 10) wpm_index = 1;
                else if (baseConfig.wpm < 15) wpm_index = 2;
                else if (baseConfig.wpm < 20) wpm_index = 3;
                else if (baseConfig.wpm < 25) wpm_index = 4;
                else if (baseConfig.wpm < 30) wpm_index = 5;
                else if (baseConfig.wpm < 35) wpm_index = 6;
                else wpm_index = 6;
                break;
        }
        gtk_combo_box_set_active(GTK_COMBO_BOX(wpm_combo), wpm_index);
    }
}

// 新增函数：保存频率和WPM配置到文件
void MainApp::save_frequency_wpm_config(GtkWidget* frequency_entry, GtkWidget* wpm_combo) {
    bool config_changed = false;
    
    // 保存频率配置
    if (frequency_entry) {
        const gchar* frequency_text = gtk_entry_get_text(GTK_ENTRY(frequency_entry));
        if (frequency_text) {
            try {
                double new_frequency = std::stod(frequency_text);
                if (new_frequency != baseConfig.currentFrequency) {
                    baseConfig.currentFrequency = new_frequency;
                    config_changed = true;
                }
            } catch (...) {
                std::cerr << "无效的频率值: " << frequency_text << std::endl;
            }
        }
    }
    
    // 保存WPM配置
    if (wpm_combo) {
        int active_index = gtk_combo_box_get_active(GTK_COMBO_BOX(wpm_combo));
        int new_wpm = 15; // 默认值
        switch (active_index) {
            case 0: new_wpm = 5; break;
            case 1: new_wpm = 10; break;
            case 2: new_wpm = 15; break;
            case 3: new_wpm = 20; break;
            case 4: new_wpm = 25; break;
            case 5: new_wpm = 30; break;
            case 6: new_wpm = 35; break;
            default: new_wpm = 15; break;
        }
        
        if (new_wpm != baseConfig.wpm) {
            baseConfig.wpm = new_wpm;
            config_changed = true;
        }
    }
    
    // 如果配置有变化，则保存到文件
    if (config_changed) {
        if (!saveBaseConfig("config/config.ini")) {
            std::cerr << "无法保存频率和WPM配置到文件" << std::endl;
        } else {
            std::cout << "成功保存频率和WPM配置到文件" << std::endl;
        }
    }
}

// 右键点击事件处理函数实现
gboolean MainApp::on_button_right_click(GtkWidget *widget, GdkEventButton *event, gpointer user_data) {
    // 检查是否是右键点击
    if (event->type == GDK_BUTTON_PRESS && event->button == 3) { // 3代表右键
        // 获取主窗口作为父窗口
        GtkBuilder *builder = GTK_BUILDER(user_data);
        GtkWidget *main_window = GTK_WIDGET(gtk_builder_get_object(builder, "main_window"));
        // 显示功能键配置对话框
        show_function_key_config_dialog(main_window, builder);
        return TRUE; // 表示事件已处理
    }
    return FALSE; // 让其他事件继续传播
}

void MainApp::connect_button_signals(GtkBuilder *builder) {
    // 定义按钮ID列表
    std::vector<std::string> buttonIds = {
        "F1Button", "F2Button", "F3Button", "F4Button", "F5Button", "F6Button",
        "F7Button", "F8Button", "F9Button", "F10Button", "F11Button", "F12Button",
        "Fun1Button", "Fun2Button", "Fun3Button", "Fun4Button", "Fun5Button", 
        "Fun6Button", "Fun7Button"
    };
    
    // 为每个按钮连接点击信号
    for (const std::string& buttonId : buttonIds) {
        GtkWidget* button = GTK_WIDGET(gtk_builder_get_object(builder, buttonId.c_str()));
        if (button) {
            // 连接按钮点击信号到FunctionButtonManager的处理函数
            g_signal_connect(button, "clicked", G_CALLBACK(FunctionButtonManager::on_function_button_clicked), builder);
            // 连接按钮右键点击信号到MainApp的处理函数
            g_signal_connect(button, "button-press-event", G_CALLBACK(MainApp::on_button_right_click), builder);
        } else {
            std::cerr << "警告: 找不到按钮 " << buttonId << std::endl;
        }
    }
    
    // 连接波段按钮的点击信号
    std::vector<std::string> bandButtons = {
        "dtpl160", "dtpl80", "dtpl40", "dtpl30", 
        "dtpl20", "dtpl15", "dtpl12", "dtpl10"
    };
    
    for (const std::string& buttonId : bandButtons) {
        GtkWidget* button = GTK_WIDGET(gtk_builder_get_object(builder, buttonId.c_str()));
        if (button) {
            // 连接波段按钮点击信号到MainApp的处理函数
            g_signal_connect(button, "clicked", G_CALLBACK(MainApp::on_dtpl_button_clicked), builder);
        } else {
            std::cerr << "警告: 找不到波段按钮 " << buttonId << std::endl;
        }
    }
    
    // 连接popover菜单中的按钮信号
    GtkWidget* cw_config_button = GTK_WIDGET(gtk_builder_get_object(builder, "cw_config_button"));
    if (cw_config_button) {
        // 连接CW配置按钮点击信号到RadioManager的处理函数
        g_signal_connect(cw_config_button, "clicked", G_CALLBACK(RadioManager::on_cw_config_clicked), builder);
    } else {
        std::cerr << "警告: 找不到CW配置按钮" << std::endl;
    }
    
    // 连接CW训练按钮点击信号
    GtkWidget* cw_trainer_button = GTK_WIDGET(gtk_builder_get_object(builder, "cw_trainer_button"));
    if (cw_trainer_button) {
        // 连接CW训练按钮点击信号到MainApp的处理函数
        g_signal_connect(cw_trainer_button, "clicked", G_CALLBACK(MainApp::on_cw_trainer_clicked), builder);
    } else {
        std::cerr << "警告: 找不到CW训练按钮" << std::endl;
    }
    
    // 连接功能键配置按钮点击信号
    GtkWidget* function_key_config_button = GTK_WIDGET(gtk_builder_get_object(builder, "function_key_config_button"));
    if (function_key_config_button) {
        // 连接功能键配置按钮点击信号到MainApp的处理函数
        g_signal_connect(function_key_config_button, "clicked", G_CALLBACK(MainApp::show_function_key_config_dialog), builder);
    } else {
        std::cerr << "警告: 找不到功能键配置按钮" << std::endl;
    }
    
    // 连接复选框信号
    GtkWidget* ckHelpWin = GTK_WIDGET(gtk_builder_get_object(builder, "ckHelpWin"));
    if (ckHelpWin) {
        g_signal_connect(ckHelpWin, "toggled", G_CALLBACK(MainApp::on_help_window_checkbox_toggled), builder);
    } else {
        std::cerr << "警告: 找不到帮助窗口复选框" << std::endl;
    }
    
    GtkWidget* ckLogWin = GTK_WIDGET(gtk_builder_get_object(builder, "ckLogWin"));
    if (ckLogWin) {
        g_signal_connect(ckLogWin, "toggled", G_CALLBACK(MainApp::on_log_window_checkbox_toggled), builder);
    } else {
        std::cerr << "警告: 找不到日志窗口复选框" << std::endl;
    }
    
    GtkWidget* ckMapWin = GTK_WIDGET(gtk_builder_get_object(builder, "ckMapWin"));
    if (ckMapWin) {
        g_signal_connect(ckMapWin, "toggled", G_CALLBACK(MainApp::on_map_window_checkbox_toggled), builder);
    } else {
        std::cerr << "警告: 找不到地图窗口复选框" << std::endl;
    }
}

void MainApp::setup_signal_handlers() {
    // 注册信号处理函数
    signal(SIGINT, signal_handler);   // Ctrl+C
    signal(SIGTERM, signal_handler);  // 终止信号
}

void MainApp::cleanup_on_exit() {
    // 检查CW端口是否打开，如果打开则关闭
    if (RadioManager::is_cw_port_open()) {
        std::cout << "程序退出，正在关闭CW端口..." << std::endl;
        RadioManager::close_cw_port();
    }
    
    // 停止并清理HTTP服务器
    if (MainApp::httpServer) {
        MainApp::httpServer->stop();
        delete MainApp::httpServer;
        MainApp::httpServer = nullptr;
    }
    
    // 清理窗口实例
    if (MainApp::helpWindowInstance) {
        delete MainApp::helpWindowInstance;
        MainApp::helpWindowInstance = nullptr;
    }
    if (MainApp::logWindowInstance) {
        delete MainApp::logWindowInstance;
        MainApp::logWindowInstance = nullptr;
    }
    if (MainApp::mapWindowInstance) {
        delete MainApp::mapWindowInstance;
        MainApp::mapWindowInstance = nullptr;
    }
}

// 主窗口显示后回调函数实现
void MainApp::on_main_window_show(GtkWidget *widget, gpointer user_data) {
    // 使用g_idle_add延迟执行，确保窗口已经完全显示和布局完成
    g_idle_add([](gpointer data) -> gboolean {
        GtkWidget *window = GTK_WIDGET(data);        
        
        // 再次使用g_idle_add进行二次确认，确保窗口完全布局完成
        g_idle_add([](gpointer data) -> gboolean {
            GtkWidget *window = GTK_WIDGET(data);
            //将 logWindow 创建移到这里，显示在主窗口下方，宽度与主窗口相同 ，高度占屏幕余下的高度
            // 初始化并显示log_grid_dialog窗口
            // 创建并保存LogGridDialog实例
            MainApp::logWindowInstance = new LogGridDialog();
            if (MainApp::logWindowInstance->init()) {
                MainApp::logWindowCreated = TRUE;
                MainApp::logWindowInstance->populate_log_data();
                
                // 获取log_grid_dialog窗口并设置位置在主窗口下方
                MainApp::logWindowWidget = MainApp::logWindowInstance->get_window();
                if (MainApp::logWindowWidget) {    
                    GtkWidget* mainWindow = GTK_WIDGET(data);
                    // 获取主窗口的位置和尺寸
                    gint mainX, mainY, mainWidth, mainHeight;
                    gtk_window_get_position(GTK_WINDOW(mainWindow), &mainX, &mainY);
                    gtk_window_get_size(GTK_WINDOW(mainWindow), &mainWidth, &mainHeight);                
                    // 获取屏幕相关信息
                    GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(mainWindow));
                    GdkDisplay* display = gdk_screen_get_display(screen);
                    GdkMonitor* monitor = gdk_display_get_primary_monitor(display);
                    
                    GdkRectangle monitor_geometry;
                    gdk_monitor_get_geometry(monitor, &monitor_geometry);
                    
                    GdkRectangle workarea_geometry;
                    gdk_monitor_get_workarea(monitor, &workarea_geometry);
                    
                    // 计算顶部面板高度
                    gint top_panel_height = monitor_geometry.height - workarea_geometry.height;
                    
                    // 计算屏幕可用宽度
                    gint screen_width = workarea_geometry.width;
                    
                    // 应用窗口配置或使用默认位置和尺寸
                    WindowConfig logConfig = WindowConfigManager::getWindowConfig("logWindow");
                    if (logConfig.is_set) {
                        gtk_window_set_default_size(GTK_WINDOW(MainApp::logWindowWidget), logConfig.width, logConfig.height);
                        gtk_window_move(GTK_WINDOW(MainApp::logWindowWidget), logConfig.x, logConfig.y);
                    } else {
                        // 设置logWindow的大小：宽度与主窗口相同，高度为剩余工作区域高度
                        gtk_window_set_default_size(GTK_WINDOW(MainApp::logWindowWidget), mainWidth, 500);
                        // 设置log窗口的位置在主窗口下方
                        gtk_window_move(GTK_WINDOW(MainApp::logWindowWidget), 0, mainHeight);
                    }
                    g_signal_connect(MainApp::logWindowWidget, "destroy", G_CALLBACK(MainApp::on_log_window_destroyed), nullptr);
                
                    // 应用窗口配置管理器
                    WindowConfigManager::applyWindowConfig(MainApp::logWindowWidget, "logWindow");
                    
                    // 根据配置决定是否显示窗口
                    if (logConfig.show) {
                        MainApp::logWindowInstance->show();
                    }
                }
            } else {
                std::cerr << "无法初始化log_grid_dialog" << std::endl;
            }
            
            // 只执行一次，返回G_SOURCE_REMOVE
            return G_SOURCE_REMOVE;
        }, window);
        
        //使用g_idle_add([](gpointer data) -> gboolean 在主窗口右边增加一个helpWindow,宽度为屏幕可用宽度减去主窗口宽度 ，高度与主窗口高度一致
        g_idle_add([](gpointer data) -> gboolean {
            GtkWidget* mainWindow = GTK_WIDGET(data);
            
            // 获取主窗口的位置和尺寸
            gint mainX, mainY, mainWidth, mainHeight;
            gtk_window_get_position(GTK_WINDOW(mainWindow), &mainX, &mainY);
            gtk_window_get_size(GTK_WINDOW(mainWindow), &mainWidth, &mainHeight);
            
            // 获取屏幕相关信息
            GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(mainWindow));
            GdkDisplay* display = gdk_screen_get_display(screen);
            GdkMonitor* monitor = gdk_display_get_primary_monitor(display);
            
            GdkRectangle monitor_geometry;
            gdk_monitor_get_geometry(monitor, &monitor_geometry);
            
            GdkRectangle workarea_geometry;
            gdk_monitor_get_workarea(monitor, &workarea_geometry);
            
            // 计算顶部面板高度
            gint top_panel_height = monitor_geometry.height - workarea_geometry.height;
            
            // 计算屏幕可用宽度
            gint screen_width = workarea_geometry.width;
            
            // 创建HelpWindow
            MainApp::helpWindowInstance = new HelpWindow();
            if (MainApp::helpWindowInstance->init()) {
                MainApp::helpWindowCreated = TRUE;
                GtkWidget* helpWin = MainApp::helpWindowInstance->get_window();
                MainApp::helpWindowWidget = helpWin;
                if (helpWin) {
                    // 应用窗口配置或使用默认位置和尺寸
                    WindowConfig helpConfig = WindowConfigManager::getWindowConfig("helpWindow");
                    if (helpConfig.is_set) {
                        gtk_window_set_default_size(GTK_WINDOW(helpWin), helpConfig.width, helpConfig.height);
                        gtk_window_move(GTK_WINDOW(helpWin), helpConfig.x, helpConfig.y);
                    } else {
                        // 计算helpWindow的位置和尺寸
                        gint helpWidth = screen_width - mainWidth;
                        gint helpHeight = mainHeight;
                        gint helpX = mainX + mainWidth;
                        gint helpY = mainY;
                        
                        // 设置helpWindow的大小和位置
                        gtk_window_set_default_size(GTK_WINDOW(helpWin), helpWidth, helpHeight);
                        gtk_window_move(GTK_WINDOW(helpWin), helpX, helpY);
                    }
                    // 连接helpWindow的destroy信号
                    g_signal_connect(helpWin, "destroy", G_CALLBACK(MainApp::on_help_window_destroyed), nullptr);
                    
                    // 应用窗口配置管理器
                    WindowConfigManager::applyWindowConfig(helpWin, "helpWindow");
                    
                    // 根据配置决定是否显示窗口
                    if (helpConfig.show) {
                        MainApp::helpWindowInstance->show();
                    }
                }
            }
            
            // 只执行一次，返回G_SOURCE_REMOVE
            return G_SOURCE_REMOVE;
        }, window);

        //使用g_idle_add([](gpointer data) -> gboolean 在logWindow右边增加一个mapWindow,宽度为屏幕可用宽度减去主窗口宽度 ，高度与logWindow高度一致
        g_idle_add([](gpointer data) -> gboolean {
            GtkWidget* mainWindow = GTK_WIDGET(data);
            
            // 获取主窗口的位置和尺寸
            gint mainX, mainY, mainWidth, mainHeight;
            gtk_window_get_position(GTK_WINDOW(mainWindow), &mainX, &mainY);
            gtk_window_get_size(GTK_WINDOW(mainWindow), &mainWidth, &mainHeight);
            
            // 获取屏幕相关信息
            GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(mainWindow));
            GdkDisplay* display = gdk_screen_get_display(screen);
            GdkMonitor* monitor = gdk_display_get_primary_monitor(display);
            
            GdkRectangle monitor_geometry;
            gdk_monitor_get_geometry(monitor, &monitor_geometry);
            
            GdkRectangle workarea_geometry;
            gdk_monitor_get_workarea(monitor, &workarea_geometry);
            
            // 计算顶部面板高度
            gint top_panel_height = monitor_geometry.height - workarea_geometry.height;
            
            // 计算屏幕可用高度
            gint screen_height = workarea_geometry.height;
            
            // 获取logWindow的位置和尺寸（假设logWindow已经创建）
            gint logX = 0, logY = mainY + mainHeight + 47; // 47是标题栏高度
            gint logWidth = mainWidth;
            gint logHeight = screen_height - mainY - mainHeight - 47 - top_panel_height;
            
            // 创建MapWindow
            MainApp::mapWindowInstance = new MapWindow();
            if (MainApp::mapWindowInstance->init()) {
                MainApp::mapWindowCreated = TRUE;
                GtkWidget* mapWin = MainApp::mapWindowInstance->get_window();
                MainApp::mapWindowWidget = mapWin;
                if (mapWin) {
                    // 应用窗口配置或使用默认位置和尺寸
                    WindowConfig mapConfig = WindowConfigManager::getWindowConfig("mapWindow");
                    if (mapConfig.is_set) {
                        gtk_window_set_default_size(GTK_WINDOW(mapWin), mapConfig.width, mapConfig.height);
                        gtk_window_move(GTK_WINDOW(mapWin), mapConfig.x, mapConfig.y);
                    } else {
                        // 计算mapWindow的位置和尺寸
                        gint mapWidth = workarea_geometry.width - mainWidth;
                        gint mapHeight = logHeight;
                        gint mapX = logX + logWidth;
                        gint mapY = logY;
                        
                        // 设置mapWindow的大小和位置
                        gtk_window_set_default_size(GTK_WINDOW(mapWin), mapWidth, mapHeight);
                        gtk_window_move(GTK_WINDOW(mapWin), mapX, mapY);
                    }
                    // 连接mapWindow的destroy信号
                    g_signal_connect(mapWin, "destroy", G_CALLBACK(MainApp::on_map_window_destroyed), nullptr);
                    
                    // 应用窗口配置管理器
                    WindowConfigManager::applyWindowConfig(mapWin, "mapWindow");
                    
                    // 根据配置决定是否显示窗口
                    if (mapConfig.show) {
                        MainApp::mapWindowInstance->show();
                    }
                }
            }
            
            // 只执行一次，返回G_SOURCE_REMOVE
            return G_SOURCE_REMOVE;
        }, window);
        


        // 只执行一次，返回G_SOURCE_REMOVE
        return G_SOURCE_REMOVE;
    }, widget);
}

// 信号处理函数实现
static void signal_handler(int sig) {
    std::cout << "接收到信号 " << sig << "，正在清理资源..." << std::endl;
    MainApp::cleanup_on_exit();
    exit(0);
}

// CW训练按钮点击处理函数实现
void MainApp::on_cw_trainer_clicked(GtkWidget *widget, gpointer data) {
    std::cout << "CW训练按钮被点击，正在启动cwtrainerX..." << std::endl;
    
    // 使用system函数运行cwtrainerX程序
    int result = system("./cwtrainerX");
    
    // 获取父窗口用于显示对话框
    GtkWidget *parent_window = gtk_widget_get_toplevel(widget);
    
    if (result == -1 || WEXITSTATUS(result) == 127) {  // 127表示命令未找到
        std::cerr << "无法启动cwtrainerX程序" << std::endl;
        
        // 显示错误对话框
        GtkWidget *dialog = gtk_message_dialog_new(
            GTK_WINDOW(parent_window),
            GTK_DIALOG_MODAL,
            GTK_MESSAGE_ERROR,
            GTK_BUTTONS_OK,
            "无法启动CW训练程序cwtrainerX。\n请确保程序已正确安装。"
        );
        
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
    } else {
        std::cout << "cwtrainerX程序已启动" << std::endl;
        
        // // 显示成功消息
        // GtkWidget *dialog = gtk_message_dialog_new(
        //     GTK_WINDOW(parent_window),
        //     GTK_DIALOG_MODAL,
        //     GTK_MESSAGE_INFO,
        //     GTK_BUTTONS_OK,
        //     "CW训练程序cwtrainerX已启动。"
        // );
        
        // gtk_dialog_run(GTK_DIALOG(dialog));
        // gtk_widget_destroy(dialog);
    }
}

// 键盘事件处理函数实现
gboolean MainApp::on_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data) {
    GtkBuilder *builder = GTK_BUILDER(user_data);
    
    // 检查是否按下了Alt+A组合键
    if ((event->keyval == GDK_KEY_a || event->keyval == GDK_KEY_A) && (event->state & GDK_MOD1_MASK)) {
        // 获取edQSOMemo文本视图组件
        GtkWidget* edQSOMemo = GTK_WIDGET(gtk_builder_get_object(builder, "edQSOMemo"));
        GtkWidget* edSendJust = GTK_WIDGET(gtk_builder_get_object(builder, "edSendJust"));
        
        if (edQSOMemo && edSendJust) {
            // 获取edQSOMemo的文本缓冲区
            GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(edQSOMemo));
            if (buffer) {
                // 检查是否有选中的文本
                GtkTextIter start, end;
                gchar *selected_text = nullptr;
                
                if (gtk_text_buffer_get_selection_bounds(buffer, &start, &end)) {
                    // 有选中的文本，复制选中的部分
                    selected_text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
                } else {
                    // 没有选中的文本，复制全部内容
                    GtkTextIter start_iter, end_iter;
                    gtk_text_buffer_get_start_iter(buffer, &start_iter);
                    gtk_text_buffer_get_end_iter(buffer, &end_iter);
                    selected_text = gtk_text_buffer_get_text(buffer, &start_iter, &end_iter, FALSE);
                }
                
                if (selected_text) {
                    // 将文本设置到edSendJust中
                    gtk_entry_set_text(GTK_ENTRY(edSendJust), selected_text);
                    g_free(selected_text);
                }
            }
        }
        
        return TRUE; // 事件已处理
    }
    
    // 检查是否按下了ESC键
    if (event->keyval == GDK_KEY_Escape) {
        // 获取Fun1Button按钮
        GtkWidget* fun1_button = GTK_WIDGET(gtk_builder_get_object(builder, "Fun1Button"));
        if (fun1_button) {
            // 触发按钮点击事件
            gtk_button_clicked(GTK_BUTTON(fun1_button));
            return TRUE; // 事件已处理
        }
    }
    
    // 按键映射：F1-F12键到对应的按钮ID
    std::map<guint, std::string> keyMap = {
        { GDK_KEY_F1, "F1Button" },
        { GDK_KEY_F2, "F2Button" },
        { GDK_KEY_F3, "F3Button" },
        { GDK_KEY_F4, "F4Button" },
        { GDK_KEY_F5, "F5Button" },
        { GDK_KEY_F6, "F6Button" },
        { GDK_KEY_F7, "F7Button" },
        { GDK_KEY_F8, "F8Button" },
        { GDK_KEY_F9, "F9Button" },
        { GDK_KEY_F10, "F10Button" },
        { GDK_KEY_F11, "F11Button" },
        { GDK_KEY_F12, "F12Button" }
    };
    
    // 检查是否按下了F1-F12键
    auto it = keyMap.find(event->keyval);
    if (it != keyMap.end()) {
        // 获取对应的按钮
        GtkWidget* button = GTK_WIDGET(gtk_builder_get_object(builder, it->second.c_str()));
        if (button) {
            // 触发按钮点击事件
            gtk_button_clicked(GTK_BUTTON(button));
            return TRUE; // 事件已处理
        }
    }
    
    // 如果不是Alt+A、ESC键或F1-F12键，让事件继续传播
    return FALSE;
}

// 新增函数：清除指定的输入框内容
void MainApp::clear_input_fields(GtkBuilder *builder) {
    // 定义需要清除的输入框ID列表
    std::vector<std::string> entryIds = {
        "edCallSign",  // 呼号输入框
        "edSnt",       // Snt输入框
        "edRcv",       // Rcv输入框
        "edName",      // Name输入框
        "edMemo"       // Memo输入框
    };
    
    // 遍历输入框ID列表，清除每个输入框的内容
    for (const std::string& entryId : entryIds) {
        GtkWidget* entry = GTK_WIDGET(gtk_builder_get_object(builder, entryId.c_str()));
        if (entry) {
            gtk_entry_set_text(GTK_ENTRY(entry), "");
        } else {
            std::cerr << "警告: 找不到输入框 " << entryId << std::endl;
        }
    }
    
    std::cout << "已清除所有输入框内容" << std::endl;
}


int MainApp::run(int argc, char *argv[]) {
    GtkBuilder *builder;
    GtkWidget *window;
    GError *error = nullptr;

    // 设置信号处理
    setup_signal_handlers();

    // Initialize HTTP server
    httpServer = new HttpServer(8001, "127.0.0.1");
    httpServer->start();

    // 设置GDK_BACKEND为x11以避免Wayland相关的警告
    // 这需要在gtk_init之前设置
    if (!getenv("GDK_BACKEND")) {
        setenv("GDK_BACKEND", "x11", 1);
    }

    // Initialize GTK
    gtk_init(&argc, &argv);

    // Load base configuration
    if (!loadBaseConfig("config/config.ini")) {
        std::cerr << "警告: 无法加载基础配置文件，将使用默认值" << std::endl;
    } else {
        std::cout << "串口配置: " << baseConfig.port << " @ " << baseConfig.baudRate << " baud" << std::endl;
        std::cout << "当前波段: " << baseConfig.currentBand << std::endl;
        std::cout << "当前频率: " << baseConfig.currentFrequency << " MHz" << std::endl;
        std::cout << "WPM: " << baseConfig.wpm << std::endl;
    }
    
    // Load Cabrillo configuration
    CabrilloConfig* cabrilloConfig = CabrilloConfig::getInstance();
    if (!cabrilloConfig->loadConfig("config/cabrilloConfig.ini")) {
        std::cerr << "警告: 无法加载Cabrillo配置文件" << std::endl;
    } else {
        std::cout << "成功加载Cabrillo配置文件" << std::endl;
        // 输出一些关键配置项用于验证
        std::cout << "Callsign: " << cabrilloConfig->get("CabrilloConfig.CALLSIGN", "未设置") << std::endl;
        std::cout << "Contest: " << cabrilloConfig->get("CabrilloConfig.CONTEST", "未设置") << std::endl;
    }

    // Load window configuration
    WindowConfigManager::loadWindowConfig("winCfg.ini");
    
    // 获取各个窗口的配置信息，用于设置复选框的初始状态
    WindowConfig helpConfig = WindowConfigManager::getWindowConfig("helpWindow");
    WindowConfig logConfig = WindowConfigManager::getWindowConfig("logWindow");
    WindowConfig mapConfig = WindowConfigManager::getWindowConfig("mapWindow");

    // Load function key configuration
    config = loadFunctionKeyConfig();
    
    // Print some config values for verification
    if (!config.empty()) {
        std::cout << "配置文件加载成功，部分配置项：" << std::endl;
        for (const auto& section : config) {
            std::cout << "Section: " << section.first << std::endl;
            for (const auto& kv : section.second) {
                std::cout << "  " << kv.first << " = " << kv.second << std::endl;
                break; // 只打印每个section的第一个配置项
            }
            if (config.size() > 3) break; // 只打印前几个section
        }
    }

    //加载 wl_cty.dat 文件
    if (!parser.loadFromFile("./config/wl_cty.dat")) {
        std::cerr << "Error loading dxcc file: " << parser.getLastError() << std::endl;
        return 1;
    }
    std::cout << "wl_cty.dat文件加载成功!" << std::endl;

    // Create builder and load UI file
    builder = UIManager::create_builder();
    
    if (!builder) {
        std::cerr << "无法加载UI文件: 所有尝试的路径都失败了" << std::endl;
        return 1;
    }

    // Get window object
    window = UIManager::get_main_window(builder);
    if (!window) {
        std::cerr << "无法获取主窗口对象" << std::endl;
        return 1;
    }
    
    // 在连接信号之前设置复选框的初始状态
    // 获取复选框组件
    GtkWidget* ckHelpWin = GTK_WIDGET(gtk_builder_get_object(builder, "ckHelpWin"));
    GtkWidget* ckLogWin = GTK_WIDGET(gtk_builder_get_object(builder, "ckLogWin"));
    GtkWidget* ckMapWin = GTK_WIDGET(gtk_builder_get_object(builder, "ckMapWin"));
    
    // 根据配置设置复选框状态
    if (ckHelpWin) {
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ckHelpWin), helpConfig.show);
    }
    if (ckLogWin) {
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ckLogWin), logConfig.show);
    }
    if (ckMapWin) {
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ckMapWin), mapConfig.show);
    }

    // Apply CSS styles
    UIManager::apply_css_styles(builder, window);

    // Connect signals
    UIManager::connect_signals(builder);
    
    // 连接主窗口的显示事件
    g_signal_connect(window, "show", G_CALLBACK(MainApp::on_main_window_show), nullptr);
        
    // Load configuration to buttons based on QSO type
    // 从Cabrillo配置中获取当前的竞赛类型
    std::string currentQsoType = cabrilloConfig->get("CabrilloConfig.CONTEST", "DX");
    GtkWidget* main_window = UIManager::get_main_window(builder);
    if (main_window) {
        load_config_to_buttons(main_window, currentQsoType, builder);
    }

    // 新增：加载配置到频率和WPM控件
    load_config_to_frequency_wpm(builder);

    // 设置dtpl按钮文本颜色为红色
    set_dtpl_red_font(builder, "dtpl"+baseConfig.currentBand);
    
    // 获取频率和WPM控件并连接信号
    GtkWidget* frequency_entry = GTK_WIDGET(gtk_builder_get_object(builder, "edFrequency"));
    GtkWidget* wpm_combo = GTK_WIDGET(gtk_builder_get_object(builder, "cmbWpm"));
    
    if (frequency_entry) {
        // 连接频率输入框的信号
        g_signal_connect(frequency_entry, "changed", G_CALLBACK(on_frequency_changed), nullptr);
        g_signal_connect(frequency_entry, "focus-out-event", G_CALLBACK(on_frequency_focus_out), builder);
        g_signal_connect(frequency_entry, "key-press-event", G_CALLBACK(on_frequency_key_press), builder);
    }
    
    if (wpm_combo) {
        // 连接WPM下拉框的选择改变信号
        g_signal_connect(wpm_combo, "changed", G_CALLBACK(on_wpm_changed), builder);
    }
    
    // Connect button signals
    connect_button_signals(builder);
    
    // 新增：连接主窗口的按键事件，用于处理F1-F12键
    g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press_event), builder);
    //设置主窗口的高度和宽度
    gtk_window_set_default_size(GTK_WINDOW(window), 922, 376);
    // 应用窗口配置
    WindowConfigManager::applyWindowConfig(window, "mainWindow");
    
    // Show window
    gtk_widget_show_all(window);
    
    // 移动窗口到 0,0（在显示之后）- 只有在没有配置时才使用默认位置
    WindowConfig mainConfig = WindowConfigManager::getWindowConfig("mainWindow");
    if (!mainConfig.is_set) {
        gtk_window_move(GTK_WINDOW(window), 0, 0);
    }
    
    // 预创建edQSOMemo的bold标签
    GtkWidget* edQSOMemo = GTK_WIDGET(gtk_builder_get_object(builder, "edQSOMemo"));
    if (edQSOMemo) {
        GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(edQSOMemo));
        GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table(buffer);
        GtkTextTag *bold_tag = gtk_text_tag_table_lookup(tag_table, "bold");
        if (!bold_tag) {
            bold_tag = gtk_text_buffer_create_tag(buffer, "bold", "weight", PANGO_WEIGHT_BOLD, nullptr);
        }
    }

    

    // Connect signal for window close event
    g_signal_connect(window, "destroy", G_CALLBACK(+[](GtkWidget* widget, gpointer data) {
        // 设置主窗口关闭标志
        MainApp::isMainWindowClosing = TRUE;
        // 调用gtk_main_quit退出主循环
        gtk_main_quit();
    }), nullptr);

    // Run main loop
    gtk_main();

    // Stop HTTP server
    if (httpServer) {
        httpServer->stop();
        delete httpServer;
        httpServer = nullptr;
    }

    // Cleanup on normal exit
    cleanup_on_exit();

    // Cleanup
    g_object_unref(builder);
    return 0;
}

/**
 * @brief 当edQSOMemo文本框内容改变时调用
 * 
 * @param data 传递给回调函数的用户数据（UpdateUIData类型）
 * @return gboolean 返回G_SOURCE_REMOVE以移除源
 */
gboolean MainApp::update_qso_memo_callback(gpointer data) {
    // 释放分配的内存
    UpdateUIData* uiData = static_cast<UpdateUIData*>(data);
    std::string cw = uiData->cw;
    int index = uiData->index;
    
    // 获取edQSOMemo组件
    GtkBuilder* builder = UIManager::get_builder();
    if (!builder) {
        std::cerr << "错误: 无法获取UI构建器" << std::endl;
        delete uiData; // 释放内存
        return G_SOURCE_REMOVE;
    }
    
    GtkWidget* edQSOMemo = GTK_WIDGET(gtk_builder_get_object(builder, "edQSOMemo"));
    if (!edQSOMemo) {
        std::cerr << "警告: 找不到edQSOMemo输入框" << std::endl;
        delete uiData; // 释放内存
        return G_SOURCE_REMOVE;
    }
    
    // 获取文本缓冲区
    GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(edQSOMemo));
    
    //index=0 清空edQSOMemo并添加cw到edQSOMemo,>0 将index位置的字符设置为bold
    if(index == 0) {
        gtk_text_buffer_set_text(buffer, "", -1);
        // 添加新文本到缓冲区末尾
        GtkTextIter end_iter;
        gtk_text_buffer_get_end_iter(buffer, &end_iter);
        gtk_text_buffer_insert(buffer, &end_iter, cw.c_str(), -1);
    }else{
        // std::cout << "index:" << index << ",cw.length:"<< cw.length() << std::endl;
        // 确保index在有效范围内
        if (index >= 0 && index < static_cast<int>(cw.length())) {
            // gtk_text_buffer_set_text(buffer, cw.c_str(), -1);
            //将index位置的字符设置为bold                        
            GtkTextIter char_start, char_end;
            gtk_text_buffer_get_iter_at_offset(buffer, &char_start, index);
            gtk_text_buffer_get_iter_at_offset(buffer, &char_end, index + 1);
            gtk_text_buffer_apply_tag_by_name(buffer, "bold", &char_start, &char_end);
        }
    }
   
    // 释放分配的内存
    delete uiData;
    
    return G_SOURCE_REMOVE;
}

// 复选框信号处理函数实现
void MainApp::on_help_window_checkbox_toggled(GtkWidget *widget, gpointer data) {
    GtkBuilder *builder = GTK_BUILDER(data);
    
    // 检查复选框是否被选中
    gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
    
    // 根据选中状态显示或隐藏帮助窗口
    if (active) {
        // 如果帮助窗口尚未创建，则创建它
        if (!MainApp::helpWindowCreated) {
            MainApp::helpWindowInstance = new HelpWindow();
            if (MainApp::helpWindowInstance->init()) {
                MainApp::helpWindowCreated = TRUE;
                MainApp::helpWindowWidget = MainApp::helpWindowInstance->get_window();
                // 应用窗口配置
                WindowConfigManager::applyWindowConfig(MainApp::helpWindowWidget, "helpWindow");
                // 连接窗口关闭事件
                g_signal_connect(MainApp::helpWindowWidget, "destroy", G_CALLBACK(MainApp::on_help_window_destroyed), nullptr);
                MainApp::helpWindowInstance->show();
            }
        } else {
            // 如果帮助窗口已创建，则显示它
            if (MainApp::helpWindowInstance) {
                MainApp::helpWindowInstance->show();
            }
        }
    } else {
        // 隐藏帮助窗口（如果已创建）
        if (MainApp::helpWindowInstance) {
            MainApp::helpWindowInstance->hide();
        }
    }
    
    // 更新内存中的配置状态
    WindowConfig helpConfig = WindowConfigManager::getWindowConfig("helpWindow");
    helpConfig.show = active;
    WindowConfigManager::setWindowConfig("helpWindow", helpConfig);
    
    // 保存配置到文件
    WindowConfigManager::saveWindowConfig("winCfg.ini");
    
    std::cout << "帮助窗口复选框状态改变: " << (active ? "选中" : "未选中") << std::endl;
}

// 窗口关闭事件处理函数实现
void MainApp::on_help_window_destroyed(GtkWidget *widget, gpointer data) {
    // 重置窗口创建状态
    MainApp::helpWindowCreated = FALSE;
    MainApp::helpWindowInstance = nullptr;
    MainApp::helpWindowWidget = nullptr;
    if(MainApp::isMainWindowClosing)
    {
        return;
    }
    
    // 更新复选框状态为未选中
    GtkBuilder* builder = UIManager::get_builder();
    if (builder) {
        GtkWidget* ckHelpWin = GTK_WIDGET(gtk_builder_get_object(builder, "ckHelpWin"));
        if (ckHelpWin) {
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ckHelpWin), FALSE);
        }
    }
    
    // 更新内存中的配置状态
    WindowConfig helpConfig = WindowConfigManager::getWindowConfig("helpWindow");
    helpConfig.show = false;
    WindowConfigManager::setWindowConfig("helpWindow", helpConfig);
    
    // 保存配置到文件
    WindowConfigManager::saveWindowConfig("winCfg.ini");
    
    std::cout << "帮助窗口已关闭，复选框状态已同步更新" << std::endl;
}

void MainApp::on_log_window_checkbox_toggled(GtkWidget *widget, gpointer data) {
    GtkBuilder *builder = GTK_BUILDER(data);
    
    // 检查复选框是否被选中
    gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
    
    // 根据选中状态显示或隐藏日志窗口
    if (active) {
        // 如果日志窗口尚未创建，则创建它
        if (!MainApp::logWindowCreated) {
            MainApp::logWindowInstance = new LogGridDialog();
            if (MainApp::logWindowInstance->init()) {
                MainApp::logWindowCreated = TRUE;
                MainApp::logWindowWidget = MainApp::logWindowInstance->get_window();
                // 应用窗口配置
                WindowConfigManager::applyWindowConfig(MainApp::logWindowWidget, "logWindow");
                // 连接窗口关闭事件
                g_signal_connect(MainApp::logWindowWidget, "destroy", G_CALLBACK(MainApp::on_log_window_destroyed), nullptr);
                MainApp::logWindowInstance->populate_log_data();
                MainApp::logWindowInstance->show();
            }
        } else {
            // 如果日志窗口已创建，则显示它
            if (MainApp::logWindowInstance) {
                MainApp::logWindowInstance->show();
            }
        }
    } else {
        // 隐藏日志窗口（如果已创建）
        if (MainApp::logWindowInstance) {
            MainApp::logWindowInstance->hide();
        }
    }
    
    // 更新内存中的配置状态
    WindowConfig logConfig = WindowConfigManager::getWindowConfig("logWindow");
    logConfig.show = active;
    WindowConfigManager::setWindowConfig("logWindow", logConfig);
    
    // 保存配置到文件
    WindowConfigManager::saveWindowConfig("winCfg.ini");
    
    std::cout << "日志窗口复选框状态改变: " << (active ? "选中" : "未选中") << std::endl;
}

// 窗口关闭事件处理函数实现
void MainApp::on_log_window_destroyed(GtkWidget *widget, gpointer data) {
    // 重置窗口创建状态
    MainApp::logWindowCreated = FALSE;
    MainApp::logWindowInstance = nullptr;
    MainApp::logWindowWidget = nullptr;
    if(MainApp::isMainWindowClosing)
    {
        return;
    }
    
    // 更新复选框状态为未选中
    GtkBuilder* builder = UIManager::get_builder();
    if (builder) {
        GtkWidget* ckLogWin = GTK_WIDGET(gtk_builder_get_object(builder, "ckLogWin"));
        if (ckLogWin) {
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ckLogWin), FALSE);
        }
    }
    
    // 更新内存中的配置状态
    WindowConfig logConfig = WindowConfigManager::getWindowConfig("logWindow");
    logConfig.show = false;
    WindowConfigManager::setWindowConfig("logWindow", logConfig);
    
    // 保存配置到文件
    WindowConfigManager::saveWindowConfig("winCfg.ini");
    
    std::cout << "日志窗口已关闭，复选框状态已同步更新" << std::endl;
}

void MainApp::on_map_window_checkbox_toggled(GtkWidget *widget, gpointer data) {
    GtkBuilder *builder = GTK_BUILDER(data);
    
    // 检查复选框是否被选中
    gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
    // 根据选中状态显示或隐藏地图窗口
    if (active) {
        // 如果地图窗口尚未创建，则创建它
        if (!MainApp::mapWindowCreated) {
            MainApp::mapWindowInstance = new MapWindow();
            if (MainApp::mapWindowInstance->init()) {
                MainApp::mapWindowCreated = TRUE;
                MainApp::mapWindowWidget = MainApp::mapWindowInstance->get_window();
                // 应用窗口配置
                WindowConfigManager::applyWindowConfig(MainApp::mapWindowWidget, "mapWindow");
                // 连接窗口关闭事件
                g_signal_connect(MainApp::mapWindowWidget, "destroy", G_CALLBACK(MainApp::on_map_window_destroyed), nullptr);
                MainApp::mapWindowInstance->show();
            }
        } else {
            // 如果地图窗口已创建，则显示它
            if (MainApp::mapWindowInstance) {
                MainApp::mapWindowInstance->show();
            }
        }
    } else {
        // 隐藏地图窗口（如果已创建）
        if (MainApp::mapWindowInstance) {
            MainApp::mapWindowInstance->hide();
        }
    }
    
    // 更新内存中的配置状态
    WindowConfig mapConfig = WindowConfigManager::getWindowConfig("mapWindow");
    mapConfig.show = active;
    WindowConfigManager::setWindowConfig("mapWindow", mapConfig);
    
    // 保存配置到文件
    WindowConfigManager::saveWindowConfig("winCfg.ini");
    
    std::cout << "地图窗口复选框状态改变: " << (active ? "选中" : "未选中") << std::endl;
}

// 窗口关闭事件处理函数实现
void MainApp::on_map_window_destroyed(GtkWidget *widget, gpointer data) {
    // 重置窗口创建状态
    MainApp::mapWindowCreated = FALSE;
    MainApp::mapWindowInstance = nullptr;
    MainApp::mapWindowWidget = nullptr;
    if(MainApp::isMainWindowClosing)
    {
        return;
    }
    // 更新复选框状态为未选中
    GtkBuilder* builder = UIManager::get_builder();
    if (builder) {
        GtkWidget* ckMapWin = GTK_WIDGET(gtk_builder_get_object(builder, "ckMapWin"));
        if (ckMapWin) {
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ckMapWin), FALSE);
        }
    }
    
    // 更新内存中的配置状态
    WindowConfig mapConfig = WindowConfigManager::getWindowConfig("mapWindow");
    mapConfig.show = false;
    WindowConfigManager::setWindowConfig("mapWindow", mapConfig);
    
    // 保存配置到文件
    WindowConfigManager::saveWindowConfig("winCfg.ini");
    
    std::cout << "地图窗口已关闭，复选框状态已同步更新" << std::endl;
}
// 日志窗口访问方法实现
gboolean MainApp::isLogWindowCreated() {
    return MainApp::logWindowCreated;
}

void MainApp::refreshLogWindowData() {
    if (MainApp::logWindowCreated && MainApp::logWindowInstance) {
        MainApp::logWindowInstance->populate_log_data();
    }
}

LogGridDialog* MainApp::getLogWindowInstance() {
    return MainApp::logWindowInstance;
}

// 显示功能键配置对话框
void MainApp::show_function_key_config_dialog(GtkWidget *parent, GtkBuilder *builder) {
    // 构建配置文件路径
    std::string configPath = "config/FunctionKeyConfig.ini";
    
    // 加载对话框UI
    GtkBuilder *dialogBuilder = gtk_builder_new();
    GError *error = nullptr;
    if (!gtk_builder_add_from_file(dialogBuilder, "UI/function_key_config_dialog.glade", &error)) {
        g_warning("无法加载功能键配置对话框UI文件: %s", error->message);
        g_error_free(error);
        g_object_unref(dialogBuilder);
        return;
    }
    
    // 获取对话框和相关控件
    GtkWidget *dialog = GTK_WIDGET(gtk_builder_get_object(dialogBuilder, "function_key_config_dialog"));
    if (!dialog) {
        g_warning("无法获取功能键配置对话框");
        g_object_unref(dialogBuilder);
        return;
    }
    
    // 设置父窗口
    if (parent) {
        gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(parent));
    }
    
    // 读取配置文件
    GKeyFile *keyFile = g_key_file_new();
    if (!g_key_file_load_from_file(keyFile, configPath.c_str(), G_KEY_FILE_NONE, &error)) {
        g_warning("无法加载功能键配置文件: %s", error->message);
        g_error_free(error);
        g_key_file_free(keyFile);
        gtk_widget_destroy(dialog);
        g_object_unref(dialogBuilder);
        return;
    }
    
    // 填充DX模式标签页的控件
    const char *dxKeys[] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
                            "Fun1", "Fun2", "Fun3", "Fun4", "Fun5", "Fun6", "Fun7"};
    
    for (const char *key : dxKeys) {
        std::string titleKey = std::string(key);// + "Title";
        std::string cwKey = std::string(key) + "CW";
        if (strncmp(key, "Fun", 3) == 0) {
            cwKey = std::string(key) + "fun";
        }
        
        char *titleValue = g_key_file_get_string(keyFile, "DX", titleKey.c_str(), nullptr);
        char *cwValue = g_key_file_get_string(keyFile, "DX", cwKey.c_str(), nullptr);
        
        std::string titleEntryName = "dx_" + std::string(key) + "_title";
        std::string cwEntryName = "dx_" + std::string(key) + "_cw";
        
        GtkWidget *titleEntry = GTK_WIDGET(gtk_builder_get_object(dialogBuilder, titleEntryName.c_str()));
        GtkWidget *cwEntry = GTK_WIDGET(gtk_builder_get_object(dialogBuilder, cwEntryName.c_str()));
        
        if (titleEntry && titleValue) {
            gtk_entry_set_text(GTK_ENTRY(titleEntry), titleValue);
        }
        
        if (cwEntry && cwValue) {
            gtk_entry_set_text(GTK_ENTRY(cwEntry), cwValue);
        }
        
        g_free(titleValue);
        g_free(cwValue);
    }
    
    // 填充CQWPX模式标签页的控件
    for (const char *key : dxKeys) {
        std::string titleKey = std::string(key);// + "Title";
        std::string cwKey = std::string(key) + "CW";        
        if (strncmp(key, "Fun", 3) == 0) {
            cwKey = std::string(key) + "fun";
        }
        
        char *titleValue = g_key_file_get_string(keyFile, "CQWPX", titleKey.c_str(), nullptr);
        char *cwValue = g_key_file_get_string(keyFile, "CQWPX", cwKey.c_str(), nullptr);
        
        std::string titleEntryName = "cqwpx_" + std::string(key) + "_title";
        std::string cwEntryName = "cqwpx_" + std::string(key) + "_cw";
        
        GtkWidget *titleEntry = GTK_WIDGET(gtk_builder_get_object(dialogBuilder, titleEntryName.c_str()));
        GtkWidget *cwEntry = GTK_WIDGET(gtk_builder_get_object(dialogBuilder, cwEntryName.c_str()));
        
        if (titleEntry && titleValue) {
            gtk_entry_set_text(GTK_ENTRY(titleEntry), titleValue);
        }
        
        if (cwEntry && cwValue) {
            gtk_entry_set_text(GTK_ENTRY(cwEntry), cwValue);
        }
        
        g_free(titleValue);
        g_free(cwValue);
    }
    
    // 显示对话框并等待响应
    gint response = gtk_dialog_run(GTK_DIALOG(dialog));
    
    if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_ACCEPT) {
        // 保存更改到配置文件
        for (const char *key : dxKeys) {
            std::string titleKey = std::string(key);// + "Title";
            std::string cwKey = std::string(key) + "CW";
            if(strncmp(key, "Fun", 3) == 0) {
                cwKey = std::string(key) + "fun";
            }
            
            std::string titleEntryName = "dx_" + std::string(key) + "_title";
            std::string cwEntryName = "dx_" + std::string(key) + "_cw";
            
            GtkWidget *titleEntry = GTK_WIDGET(gtk_builder_get_object(dialogBuilder, titleEntryName.c_str()));
            GtkWidget *cwEntry = GTK_WIDGET(gtk_builder_get_object(dialogBuilder, cwEntryName.c_str()));
            
            if (titleEntry) {
                const char *titleText = gtk_entry_get_text(GTK_ENTRY(titleEntry));
                g_key_file_set_string(keyFile, "DX", titleKey.c_str(), titleText);
            }
            
            if (cwEntry) {
                const char *cwText = gtk_entry_get_text(GTK_ENTRY(cwEntry));
                g_key_file_set_string(keyFile, "DX", cwKey.c_str(), cwText);
            }
        }
        
        // 保存CQWPX模式的更改
        for (const char *key : dxKeys) {
            std::string titleKey = std::string(key);// + "Title";
            std::string cwKey = std::string(key) + "CW";
            if(strncmp(key, "Fun", 3) == 0) {
                cwKey = std::string(key) + "fun";
            }
            
            std::string titleEntryName = "cqwpx_" + std::string(key) + "_title";
            std::string cwEntryName = "cqwpx_" + std::string(key) + "_cw";
            
            GtkWidget *titleEntry = GTK_WIDGET(gtk_builder_get_object(dialogBuilder, titleEntryName.c_str()));
            GtkWidget *cwEntry = GTK_WIDGET(gtk_builder_get_object(dialogBuilder, cwEntryName.c_str()));
            
            if (titleEntry) {
                const char *titleText = gtk_entry_get_text(GTK_ENTRY(titleEntry));
                g_key_file_set_string(keyFile, "CQWPX", titleKey.c_str(), titleText);
            }
            
            if (cwEntry) {
                const char *cwText = gtk_entry_get_text(GTK_ENTRY(cwEntry));
                g_key_file_set_string(keyFile, "CQWPX", cwKey.c_str(), cwText);
            }
        }
        
        // 写入配置文件
        GError *saveError = nullptr;
        if (!g_key_file_save_to_file(keyFile, configPath.c_str(), &saveError)) {
            g_warning("无法保存功能键配置文件: %s", saveError->message);
            g_error_free(saveError);
        }

        // 调用load_config_to_buttons更新按钮
        // 获取当前QSO类型
        CabrilloConfig* cabrilloConfig = CabrilloConfig::getInstance();
        std::string currentQsoType = cabrilloConfig->get("CabrilloConfig.CONTEST", "DX");
        GtkWidget* main_window = UIManager::get_main_window(builder);
        if(main_window) {
            config = MainApp::loadFunctionKeyConfig(); // 重新加载配置到内存
            MainApp::load_config_to_buttons(main_window, currentQsoType, builder);
        }
    }
    
    // 清理资源
    g_key_file_free(keyFile);
    gtk_widget_destroy(dialog);
    g_object_unref(dialogBuilder);
}